{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "outputs": [],
   "source": [
    "import geatpy as ea\n",
    "import numpy as np"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "import linear_model as model\n",
    "import src.project1.submit.AI as ai\n",
    "from experiment.评估函数.simulator import Simulator\n",
    "from src.project1.experimental.贪心不败机 import AI as 贪心不败机\n",
    "import 算子 as 算子\n",
    "\n",
    "chessboard_size = 8\n",
    "time_out = 10\n",
    "\n",
    "\n",
    "def 组合策略1(Vars):\n",
    "    PVT, PVT_max = 算子.get_PVT_and_max(Vars[0:10])\n",
    "\n",
    "    def _组合策略1(chessboard, color, rounds):\n",
    "        v_position = 算子.value_of_positions(chessboard, color, PVT, PVT_max)\n",
    "        v_mobility = 算子.value_of_mobility(chessboard, color, PVT, PVT_max)\n",
    "        v_edge_sta = 算子.value_of_edge_stability(chessboard, color)\n",
    "        if rounds <= 24:\n",
    "            return v_position * Vars[10] + v_mobility * Vars[11] + v_edge_sta * Vars[12]\n",
    "        else:\n",
    "            return v_position * Vars[13] + v_mobility * Vars[14] + v_edge_sta * Vars[15]\n",
    "\n",
    "    return _组合策略1\n",
    "\n",
    "\n",
    "def evalWinRate(Vars, diff=0.01, at_least_times=20):\n",
    "    wins = 0\n",
    "    cnts = 0\n",
    "    prev_prob = np.ones(at_least_times) * 100  # 不合法\n",
    "    prob = -1  # 不合法\n",
    "    while np.absolute(prob - prev_prob).sum() > at_least_times * diff or prob == 1:\n",
    "        for i_color in [ai.COLOR_BLACK, ai.COLOR_WHITE]:\n",
    "            agents = {i_color: 贪心不败机(chessboard_size, i_color, time_out, 组合策略1(Vars)),\n",
    "                      -i_color: 贪心不败机(chessboard_size, -i_color, time_out, 算子.random_base_line)}\n",
    "            simulator = Simulator(chessboard_size, time_out, agents)\n",
    "            winner = simulator.quick_run(no_print=True)\n",
    "            if winner != i_color:\n",
    "                # print(\"loss\")\n",
    "                pass\n",
    "            else:\n",
    "                # print(\"win\")\n",
    "                wins += 1\n",
    "            cnts += 1\n",
    "            prev_prob = np.append(prev_prob[1:], prob)\n",
    "            prob = wins / cnts\n",
    "    print(cnts)\n",
    "    return prob\n",
    "\n",
    "# evalWinRate(np.array([9, 10, 18, 5, 19,15, 18, 13, 8, 3, 0.03, 0.4, 0.6, 0.03, 0.6, 0.4]))\n",
    "# evalWinRate(np.array([3, 19, 10, 5,18, 10, 10,10, 8,3,0.7, 0.1, 0.2,0.6, 0.2, 0.2,]))  # 0.93\n",
    "evalWinRate(np.array([0.60791015625,4.0478515625,16.010704040527344,5.0,19.0,20.0,17.980430603027344,13.0,12.8125,-18.287429809570312,1.0,0.1,0.2,0.6,0.2,0.2]))  # 0.93\n",
    "\n",
    "# timeit 对0.01的结果 一轮需要43.1 s ± 14 s per loop (mean ± std. dev. of 7 runs, 1 loop each)， 50多次循环"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "dim = 16\n",
    "# varTypes = np.ones(dim) # 整数\n",
    "varTypes = np.zeros(dim)  # 实数\n",
    "lb = np.ones(dim) * -20\n",
    "ub = np.ones(dim) * 20\n",
    "lb[10:] = 0\n",
    "ub[10:] = 1\n",
    "delta = np.ones(dim)\n",
    "delta[10:] = 0.1\n",
    "def evalBetterThanNeighbour(Vars):\n",
    "    cnt = 0\n",
    "    for neighbour in model.neighbours(Vars, delta, lb, ub, 4):\n",
    "        for i_color in [ai.COLOR_BLACK, ai.COLOR_WHITE]:\n",
    "            agents = {i_color: 贪心不败机(chessboard_size, i_color, time_out, 组合策略1(Vars)),\n",
    "                  -i_color: 贪心不败机(chessboard_size, -i_color, time_out, 组合策略1(neighbour))}\n",
    "            simulator = Simulator(chessboard_size, time_out, agents)\n",
    "            winner = simulator.quick_run(no_print=True)\n",
    "            if winner != i_color:\n",
    "                cnt+=1\n",
    "    # 一般有40次对决\n",
    "    return (cnt/40)-0.5 # 违反约束的程度，被很多邻居打败就违反了\n",
    "def play_times(dim):\n",
    "    players = dim*2 + 1\n",
    "    return players*(players-1)//2\n",
    "print(play_times(4))\n",
    "# 值域 -0.5 0.5  -0.5最好，输得少\n",
    "# evalBetterThanNeighbour(np.array([3, 19, 10, 5,18, 10, 10,10, 8,3, 0.7, 0.1, 0.2,0.6, 0.2, 0.2,]))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "# 构建问题\n",
    "@ea.Problem.single\n",
    "def evalVars(Vars):  # 定义目标函数（含约束）\n",
    "    # f = evalWinRate(Vars)  # 计算目标函数值\n",
    "    # # CV = np.array(evalBetterThanNeighbour(Vars))\n",
    "    # CV = np.array([0])\n",
    "    f = -evalBetterThanNeighbour(Vars)  # 计算目标函数值, 要求最大值\n",
    "    CV = np.array(0.85-evalWinRate(Vars)) # 胜率不得低于这么多\n",
    "    return f, CV\n",
    "\n",
    "\n",
    "\n",
    "problem = ea.Problem(name='演化计算求解最优评估函数',\n",
    "                     M=1,  # 目标维数\n",
    "                     maxormins=[-1],  # 目标最小最大化标记列表，1：最小化该目标；-1：最大化该目标\n",
    "                     Dim=dim,  # 决策变量维数\n",
    "                     varTypes=varTypes,  # 决策变量的类型列表，0：实数；1：整数\n",
    "                     lb=lb,  # 决策变量下界\n",
    "                     ub=ub,  # 决策变量上界\n",
    "                     evalVars=evalVars)\n",
    "# 构建算法\n",
    "algorithm = ea.soea_SEGA_templet(problem,\n",
    "                                 ea.Population(Encoding='RI', NIND=16),\n",
    "                                 MAXGEN=80,  # 最大进化代数。\n",
    "                                 # MAXGEN=10,  # 最大进化代数。\n",
    "                                 logTras=1,  # 表示每隔多少代记录一次日志信息，0表示不记录。\n",
    "                                 trappedValue=1e-6,  # 单目标优化陷入停滞的判断阈值。\n",
    "                                 maxTrappedCount=10)  # 进化停滞计数器最大上限值。\n",
    "# 求解\n",
    "res = ea.optimize(algorithm, prophet=np.array([[3, 19, 10, 5,18, 10, 10,10, 8,3,0.7, 0.1, 0.2,0.6, 0.2, 0.2],\n",
    "                                               [9, 10, 18, 5, 19, 15, 18, 13, 8, 3, 0.7, 0.1, 0.2,0.6, 0.2, 0.2]]),\n",
    "                  seed=128, verbose=True, drawing=1, outputMsg=True, drawLog=True, saveFlag=True, dirName='result')"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.10.5 64-bit",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.5"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "d4ad195ff334c471a543b0a7bb226f1a689063219ec9cc66cee2dec60707a1ec"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}